import { Terminal } from 'xterm';

export function dump_file(ab: any, name: string) {
  if (!(ab instanceof Array)) {
    ab = [ab];
  }

  var blob = new Blob(ab);
  download(blob, name);
}

export function download(file_or_blob: Blob, name: string) {
  var a = document.createElement("a");
  a["download"] = name;
  a.href = window.URL.createObjectURL(file_or_blob);
  a.dataset["downloadurl"] = [
    "application/octet-stream",
    a["download"],
    a.href,
  ].join(":");

  if (document.createEvent) {
    var ev = document.createEvent("MouseEvent");
    ev.initMouseEvent(
      "click",
      true,
      true,
      window,
      0,
      0,
      0,
      0,
      0,
      false,
      false,
      false,
      false,
      0,
      null
    );
    a.dispatchEvent(ev);
  } else {
    a.click();
  }

  window.URL.revokeObjectURL(a.href);
}

interface ProgressBarOptions {
  progressBarWidth?: number;
  showSpinner?: boolean;
  spinnerChars?: string[];
  updateInterval?: number;
  onComplete?: () => void;
}

interface ProgressBar {
  start: () => void;
  stop: () => void;
  updateProgress: (newProgress: number) => void;
}

export function createProgressBar(
  term: Terminal,
  options: ProgressBarOptions
): ProgressBar {
  const {
    progressBarWidth = 50,
    showSpinner = true,
    spinnerChars = ["-", "\\", "|", "/"],
    updateInterval = 100,
    onComplete,
  } = options;

  let progress = 0;
  let spinnerIndex = 0;
  let intervalId: ReturnType<typeof setInterval> | null = null;
  let running = false;

  function start() {
    running = true;
    intervalId = setInterval(updateProgressBar, updateInterval);
  }

  function stop() {
    if (!running || intervalId === null) return;
    clearInterval(intervalId);
    running = false;
  }

  function updateProgress(newProgress: number) {
    progress = newProgress;
    updateProgressBar();
  }

  function updateProgressBar() {
    if (progress <= 100) {
      const progressBar =
        "[" +
        "=".repeat(Math.floor((progress * progressBarWidth) / 100)) +
        ">".repeat(progress < 100 ? 1 : 0) +
        " ".repeat(
          progressBarWidth -
            Math.floor((progress * progressBarWidth) / 100) -
            (progress < 100 ? 1 : 0)
        ) +
        "] " +
        progress +
        "% " +
        (showSpinner ? spinnerChars[spinnerIndex] : "");

      term.write("\r" + progressBar);
      spinnerIndex = (spinnerIndex + 1) % spinnerChars.length;
    }
  }

  return {
    start,
    stop,
    updateProgress,
  };
}
